package admin

import (
	"config-client-v1/model"
	local_oss "config-client-v1/utils/local-oss"
	"config-client-v1/utils/tools"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type UserController struct {
}

func (con UserController) List(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Username string `json:"username"`
		RealName string `json:"realname"`
		model.QueryData
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	var count int64
	list := make([]*model.User, 0)
	tx := model.DB.Model(&model.User{}).Where("del = 0").Where("project_id = ?", userToken.ProjectID)
	if param.RealName != "" {
		tx.Where("realname like ?", "%"+param.RealName+"%")
	}
	if param.Username != "" {
		tx.Where("username like ?", "%"+param.Username+"%")
	}
	err = tx.Count(&count).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	err = tx.Preload("RoleInfo").Offset(param.StartPage()).Limit(param.PageSize).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list":  list,
			"count": count,
		},
	})
}

func (con UserController) Detail(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Id int `json:"id"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	info := model.User{}
	err := model.DB.Where("id = ? AND project_id = ?", param.Id, userToken.ProjectID).First(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"data": info,
		},
	})
}

func (con UserController) Save(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	params := model.User{}
	err := ctx.ShouldBind(&params)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": err.Error(),
		})
		return
	}
	if params.Role == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "请选择用户角色",
		})
		return
	}
	roleOld := model.AuthRole{}
	roleExist, err := roleOld.Exists(params.Role)
	if !roleExist {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的角色",
			"data":    err,
		})
		return
	}
	if params.Avatar != "" {
		exist, _ := local_oss.ObjectExist(params.Avatar)
		if !exist {
			ctx.JSON(200, gin.H{
				"code":    7,
				"message": "文件已失效,请重新上传",
			})
			return
		}
		newPath, err2 := local_oss.ObjectMove(params.Avatar, "upload/avatar/")
		if err2 != nil {
			ctx.JSON(200, gin.H{
				"code":    7,
				"message": err2.Error(),
			})
			return
		}
		params.Avatar = newPath
	}
	if params.Id == 0 {
		if params.Password == "" {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "密码不能为空",
			})
			return
		}
		userExist := model.User{}
		err = model.DB.Where("project_id = ? AND username = ?", userToken.ProjectID, params.Username).Find(&userExist).Error
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    6,
				"message": err.Error(),
			})
			return
		}
		if userExist.Id != 0 {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": "用户账号已存在",
			})
			return
		}
		now := tools.GetNow()
		params.Password = tools.Md5(params.Password + LOGIN_KEY)
		params.CreateTime = &now
		params.UpdateTime = &now
		params.Status = 1
		params.ProjectID = userToken.ProjectID
		err = model.DB.Create(&params).Error
	} else {
		userExist := model.User{}
		err = model.DB.Where("id = ?", params.Id).First(&userExist).Error
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    6,
				"message": err.Error(),
			})
			return
		}
		userNameExist := model.User{}
		err = model.DB.Where("id != ? AND project_id = ? AND  username = ?", params.Id, userToken.ProjectID, params.Username).Limit(1).Find(&userNameExist).Error
		if err != nil {
			ctx.JSON(200, gin.H{
				"code":    6,
				"message": err.Error(),
			})
			return
		}
		if userNameExist.Id != 0 {
			ctx.JSON(200, gin.H{
				"code":    7,
				"message": "用户账号已存在",
			})
			return
		}

		updateData := make(map[string]interface{})
		updateData["role"] = params.Role
		updateData["username"] = params.Username
		updateData["realname"] = params.Realname
		updateData["gender"] = params.Gender
		updateData["tel"] = params.Tel
		updateData["desc"] = params.Desc
		updateData["update_time"] = tools.GetNow()
		if params.Password != "" {
			updateData["password"] = tools.Md5(params.Password + LOGIN_KEY)
		}
		if params.Avatar != "" {
			updateData["avatar"] = params.Avatar
		}
		tx := model.DB.Model(&model.User{}).Where("id = ?", params.Id)
		err = tx.Updates(&updateData).Error
	}
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

func (con UserController) Delete(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Id int `json:"id"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	info := model.User{}
	err := model.DB.Where("id = ? AND project_id = ?", param.Id, userToken.ProjectID).First(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	projectExist := &model.Project{}
	_, _ = projectExist.Exists(userToken.ProjectID)
	if projectExist.UID == info.Id {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": "初始管理员不能删除",
		})
		return
	}
	err = model.DB.Model(&model.User{}).Where("id = ?", param.Id).Update("del", 1).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
	})
}

func (con UserController) Status(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Id     int `json:"id"`
		Status int `json:"status"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	admin := model.User{}
	err := model.DB.Where("id = ? and project_id = ?", param.Id, userToken.ProjectID).First(&admin).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	if param.Status == 2 {
		param.Status = 2
	} else {
		param.Status = 1
	}
	err = model.DB.Model(&model.User{}).Where("id = ?", param.Id).Update("status", param.Status).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
	})
}

func (con UserController) RoleList(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Name string `json:"name"`
		model.QueryData
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	var count int64
	list := make([]model.AuthRole, 0)
	tx := model.DB.Model(&model.AuthRole{}).Where("del = 0").Where("project_id = ?", userToken.ProjectID)
	if param.Name != "" {
		tx.Where("name like ?", "%"+param.Name+"%")
	}
	err = tx.Count(&count).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	err = tx.Offset(param.StartPage()).Limit(param.PageSize).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list":  list,
			"count": count,
		},
	})
}

func (con UserController) RoleDetail(ctx *gin.Context) {
	param := struct {
		Id int `json:"id"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	info := model.AuthRole{}
	err := model.DB.Where("id = ?", param.Id).First(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"data": info,
		},
	})
}

func (con UserController) RoleSave(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	params := model.AuthRole{}
	err := ctx.ShouldBind(&params)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": err.Error(),
		})
		return
	}
	now := tools.GetNow()
	if params.Id == 0 {
		params.ProjectID = userToken.ProjectID
		params.CreateTime = &now
		params.UpdateTime = &now
		err = model.DB.Create(&params).Error
	} else {
		params.UpdateTime = &now
		err = model.DB.Model(&model.AuthRole{}).Where("id = ?", params.Id).Select("*").Omit("project_id,create_time").Updates(&params).Error
	}
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
	})
}

func (con UserController) RoleDelete(ctx *gin.Context) {
	param := struct {
		Id int `json:"id"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	admin := model.AuthRole{}
	err := model.DB.Where("id = ?", param.Id).First(&admin).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	err = model.DB.Model(&model.AuthRole{}).Where("id = ?", param.Id).Update("del", 1).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	err = model.DB.Model(&model.User{}).Where("role = ?", param.Id).Update("role", 0).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
	})
}

func (con UserController) RoleStatus(ctx *gin.Context) {
	param := struct {
		Id int `json:"id"`
	}{}
	_ = ctx.ShouldBindBodyWith(&param, binding.JSON)
	if param.Id == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "缺少参数",
		})
		return
	}
	admin := model.AuthRole{}
	err := model.DB.Where("id = ?", param.Id).First(&admin).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	var toStatus uint8
	if admin.Status == 0 {
		toStatus = 1
	} else {
		toStatus = 0
	}
	err = model.DB.Model(&model.AuthRole{}).Where("id = ?", param.Id).Update("status", toStatus).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
	})
}
